`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/10/20 09:56:19
// Design Name: 
// Module Name: acquire
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

//! 经过 ILA 测试，本模块无问题
module acquire(

    input           clk,
    input           rst_n,

    //! data
    input   [38:0]  pin_39,

    //! ctrl signal
    input   [31:0]  pl_cnt,
    input           trigger,
    output  reg     acq_done,

    //! write fifo
    output	reg		fifo_wr_en,
    output	[63:0]	fifo_din,
    input			fifo_full,              //TODO not used
    input			fifo_almost_full,       //TODO not used
    input			fifo_wr_rst_busy        //TODO not used
    );

localparam  IDLE    = 2'd0;
localparam  ACQUIRE = 2'd1;
localparam  DONE    = 2'd2;
localparam  WAIT    = 2'd3;

reg [1:0]   state;
reg [1:0]   next_state;
reg [31:0]  data_num;
reg [31:0]  data_cnt;

assign fifo_din = {25'b1111111111111111111111111, pin_39[38:0]};

//! 切换状态
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= IDLE;
    end else begin
        state <= next_state;
    end
end
//! 次态逻辑
always @(*) begin
    case (state)
        IDLE: begin
            if (trigger) begin
                next_state = ACQUIRE;
            end else begin
                next_state = IDLE;
            end
        end
        ACQUIRE: begin
            if (data_cnt == data_num) begin
                next_state = DONE;
            end else begin
                next_state = ACQUIRE;
            end
        end
        DONE: begin
            next_state = WAIT;
        end
        WAIT: begin
            next_state = IDLE;
        end
        default: next_state = IDLE;
    endcase
end
//! 状态机输出
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        data_num    <= 0;
        data_cnt    <= 0;
        acq_done    <= 0;
        fifo_wr_en  <= 0;
    end else begin
        case (state)
            IDLE: begin
                data_num <= pl_cnt - 1;
                data_cnt <= 0;
                acq_done <= 0;
                fifo_wr_en <= 0;
            end
            ACQUIRE: begin
                //! write fifo
                fifo_wr_en <= 1;
                acq_done <= 0;
                data_cnt <= data_cnt + 1;
            end
            DONE: begin
                data_cnt <= 0;
                fifo_wr_en <= 0;
                acq_done <= 0;
            end
            WAIT: begin
                fifo_wr_en <= 0;
                acq_done <= 1;
                data_cnt <= 0;
            end
        endcase
    end
end

endmodule
